/******************************************************************************
 cnome: A C++ source "genes" discover. :-)

 See more details at:

   http://www.codeplex.com/cnome

 The original author site is at: http://www.alemosbarbosa.com/

 Copyright (c) 2008-2010 Alexandre Lemos Barbosa.
 Distributed under the MIT License. (See accompanying file LICENSE-MIT.txt 
 or at http://www.codeplex.com/cnome/license)
 ******************************************************************************/

#include "cnome_config.h"

#include <boost/spirit/include/classic_core.hpp>
#include <boost/spirit/include/classic_dynamic.hpp>
#include <boost/wave/cpplexer/cpp_lex_token.hpp> 

#include <stdio.h>

#include "tokens.h"

#include "actions.h"
#include "typedefs.h"
#include "util.h"

namespace cnome {
using namespace actions;
using namespace boost::spirit::classic;
using namespace boost::wave;
using namespace util;

rule_t const    _THIS =
                    ch_p(T_THIS)
                ;

rule_t const    RIGHTPAREN =
                    ch_p(T_RIGHTPAREN)
                ;

rule_t const    LEFTPAREN =
                    ch_p(T_LEFTPAREN)
                ;

rule_t const    RIGHTBRACKET =
                    ch_p(T_RIGHTBRACKET)
                ;

rule_t const    LEFTBRACKET =
                    ch_p(T_LEFTBRACKET)
                ;

rule_t const    RIGHTBRACE =
                    ch_p(T_RIGHTBRACE)
                ;

rule_t const    LEFTBRACE =
                    ch_p(T_LEFTBRACE)
                ;

rule_t const    COMPL =
                    ch_p(T_COMPL)
                ;

rule_t const    TEMPLATE =
                    ch_p(T_TEMPLATE)
                ;

rule_t const    INT_ =
                    ch_p(T_INT)      
                ;

rule_t const    COLON_COLON =
                    ch_p(T_COLON_COLON)
                ;

rule_t const    SEMICOLON =
                    ch_p(T_SEMICOLON)
                ;

rule_t const    FRIEND =
                    ch_p(T_FRIEND)
                ;

rule_t const    TYPEDEF =
                    ch_p(T_TYPEDEF)
                ;

rule_t const    AUTO =
                    ch_p(T_AUTO)    
                ;

rule_t const    REGISTER =
                    ch_p(T_REGISTER) 
                ;

rule_t const    STATIC =
                    ch_p(T_STATIC)   
                ;

rule_t const    EXTERN =
                    ch_p(T_EXTERN)   
                ;

rule_t const    MUTABLE =
                    ch_p(T_MUTABLE)
                ;

rule_t const    INLINE =    
                    ch_p(T_INLINE)    
                ;

rule_t const    VIRTUAL =                   
                    ch_p(T_VIRTUAL)   
                ;

rule_t const    EXPLICIT =                  
                    ch_p(T_EXPLICIT) 
                ;

rule_t const    CHAR_ =                 
                    ch_p(T_CHAR) 
                ;

rule_t const    WCHART =                    
                    ch_p(T_WCHART)   
                ;

rule_t const    BOOL_ =                 
                    ch_p(T_BOOL)     
                ;

rule_t const    SHORT_ =                    
                    ch_p(T_SHORT)    
                ;

rule_t const    LONG_ =                 
                    ch_p(T_LONG)     
                ;

rule_t const    SIGNED =                    
                    ch_p(T_SIGNED)   
                ;

rule_t const    UNSIGNED =                  
                    ch_p(T_UNSIGNED) 
                ;

rule_t const    FLOAT_ =                    
                    ch_p(T_FLOAT)    
                ;

rule_t const    DOUBLE_ =                   
                    ch_p(T_DOUBLE)   
                ;

rule_t const    VOID_ =                 
                    ch_p(T_VOID)
                ;

rule_t const    COMMA =                 
                    ch_p(T_COMMA)
                ;

rule_t const    ENUM =                  
                    ch_p(T_ENUM)
                ;

rule_t const    TYPENAME =                  
                    ch_p(T_TYPENAME)
                ;

rule_t const    NAMESPACE =                 
                    ch_p(T_NAMESPACE)
                ;

rule_t const    USING =                 
                    ch_p(T_USING)
                ;

rule_t const    ASM =                   
                    ch_p(T_ASM)
                ;

rule_t const    ASSIGN =                    
                    ch_p(T_ASSIGN)
                ;

rule_t const    STAR =
                    ch_p(T_STAR)
                ;

rule_t const    AND =
                    ch_p(T_AND)
                ;

rule_t const    CONST_ =
                    ch_p(T_CONST)
                ;

rule_t const    VOLATILE =
                    ch_p(T_VOLATILE)
                ;

rule_t const    ELLIPSIS =
                    ch_p(T_ELLIPSIS)
                ;

rule_t const    TRY =
                    ch_p(T_TRY)
                ;

rule_t const    CATCH =
                    ch_p(T_CATCH)
                ;

rule_t const    THROW =
                    ch_p(T_THROW)
                ;

rule_t const    CLASS =
                    ch_p(T_CLASS)
                ;

rule_t const    STRUCT  =
                    ch_p(T_STRUCT )
                ;
                    
rule_t const    UNION =
                    ch_p(T_UNION)
                ;

rule_t const    COLON =
                    ch_p(T_COLON)
                ;

rule_t const    INTLIT =
                    ch_p(T_INTLIT)
                ;

rule_t const    CHARLIT =
                    ch_p(T_CHARLIT)
                ;

rule_t const    FLOATLIT =
                    ch_p(T_FLOATLIT)
                ;

rule_t const    STRINGLIT =
                    ch_p(T_STRINGLIT)
                ;

rule_t const    FALSE_ =
                    ch_p(T_FALSE)
                ;

rule_t const    TRUE_ =
                    ch_p(T_TRUE)
                ;

rule_t const    BOOLLIT =
                    TRUE_ | FALSE_
                ;


rule_t const    PRIVATE =
                    ch_p(T_PRIVATE)
                ;
            
rule_t const    PROTECTED =
                    ch_p(T_PROTECTED)
                ;
            
rule_t const    PUBLIC =
                    ch_p(T_PUBLIC)
                ;

rule_t const    IF =
                    ch_p(T_IF)
                ;

rule_t const    ELSE =
                    ch_p(T_ELSE)
                ;

rule_t const    SWITCH =
                    ch_p(T_SWITCH)
                ;

rule_t const    WHILE =
                    ch_p(T_WHILE)
                ;

rule_t const    DO =
                    ch_p(T_DO)
                ;
            
rule_t const    FOR =
                    ch_p(T_FOR)
                ;

rule_t const    BREAK =
                    ch_p(T_BREAK)
                ;

rule_t const    CONTINUE =
                    ch_p(T_CONTINUE)
                ;

rule_t const    RETURN =
                    ch_p(T_RETURN)
                ;

rule_t const    CASE =
                    ch_p(T_CASE)
                ;

rule_t const    DEFAULT =
                    ch_p(T_DEFAULT)
                ;

rule_t const    GOTO =
                    ch_p(T_GOTO)
                ;

rule_t const    DYNAMIC_CAST =
                    ch_p(T_DYNAMICCAST)
                ;

rule_t const    LESS =
                    ch_p(T_LESS)
                ;

rule_t const    GREATER =
                    ch_p(T_GREATER)
                ;

rule_t const    STATIC_CAST =
                    ch_p(T_STATICCAST)
                ;

rule_t const    REINTERPRET_CAST =
                    ch_p(T_REINTERPRETCAST)
                ;

rule_t const    CONST_CAST =
                    ch_p(T_CONSTCAST)
                ;

rule_t const    TYPEID =
                    ch_p(T_TYPEID)
                ;

rule_t const    DOT =
                    ch_p(T_DOT)
                ;

rule_t const    ARROW =
                    ch_p(T_ARROW)
                ;

rule_t const    PLUSPLUS =
                    ch_p(T_PLUSPLUS)
                ;

rule_t const    MINUSMINUS =
                    ch_p(T_MINUSMINUS)
                ;

rule_t const    SIZEOF =
                    ch_p(T_SIZEOF)
                ;

rule_t const    PLUS =
                    ch_p(T_PLUS)
                ;

rule_t const    MINUS =
                    ch_p(T_MINUS)
                ;

rule_t const    NEW =
                    ch_p(T_NEW)
                ;

rule_t const    DELETE_ =
                    ch_p(T_DELETE)
                ;

rule_t const    OROR =
                    ch_p(T_OROR)
                ;

rule_t const    QUESTION_MARK =
                    ch_p(T_QUESTION_MARK)
                ;

rule_t const    STARASSIGN =
                    ch_p(T_STARASSIGN)
                ;

rule_t const    DIVIDEASSIGN =
                    ch_p(T_DIVIDEASSIGN)
                ;

rule_t const    PERCENTASSIGN =
                    ch_p(T_PERCENTASSIGN)
                ;

rule_t const    PLUSASSIGN =
                    ch_p(T_PLUSASSIGN)
                ;

rule_t const    MINUSASSIGN =
                    ch_p(T_MINUSASSIGN)
                ;

rule_t const    SHIFTRIGHT =
                    ch_p(T_SHIFTRIGHT)
                ;

rule_t const    SHIFTLEFT =
                    ch_p(T_SHIFTLEFT)
                ;

rule_t const    SHIFTRIGHTASSIGN =
                    ch_p(T_SHIFTRIGHTASSIGN)
                ;

rule_t const    SHIFTLEFTASSIGN =
                    ch_p(T_SHIFTLEFTASSIGN)
                ;

rule_t const    ANDASSIGN =
                    ch_p(T_ANDASSIGN)
                ;

rule_t const    XORASSIGN =
                    ch_p(T_XORASSIGN)
                ;

rule_t const    ORASSIGN =
                    ch_p(T_ORASSIGN)
                ;

rule_t const    ANDAND =
                    ch_p(T_ANDAND)
                ;

rule_t const    OR =
                    ch_p(T_OR)
                ;

rule_t const    XOR =
                    ch_p(T_XOR)
                ;

rule_t const    EQUAL =
                    ch_p(T_EQUAL)
                ;

rule_t const    NOTEQUAL =
                    ch_p(T_NOTEQUAL)
                ;

rule_t const    LESSEQUAL =
                    ch_p(T_LESSEQUAL)
                ;

rule_t const    GREATEREQUAL =
                    ch_p(T_GREATEREQUAL)
                ;

rule_t const    DIVIDE =
                    ch_p(T_DIVIDE)
                ;

rule_t const    PERCENT =
                    ch_p(T_PERCENT)
                ;

rule_t const    DOTSTAR =
                    ch_p(T_DOTSTAR)
                ;

rule_t const    ARROWSTAR =
                    ch_p(T_ARROWSTAR)
                ;

rule_t const    OPERATOR =
                    ch_p(T_OPERATOR)
                ;

rule_t const    NEW_S =
                    (NEW >> LEFTBRACKET >> RIGHTBRACKET)
                ;

rule_t const    DELETE_S =
                    (DELETE_ >> LEFTBRACKET >> RIGHTBRACKET)
                ;


rule_t const    BRACKETS =
                    (LEFTBRACKET >> RIGHTBRACKET)
                ;

rule_t const    PARENS =
                    (LEFTPAREN >> RIGHTPAREN)
                ;

rule_t const    NOT =
                    ch_p(T_NOT)
                ;

rule_t const    EXPORT =
                    ch_p(T_EXPORT)
                ;

rule_t const    IDENTIFIER_HELPER(
                    ch_p(T_IDENTIFIER), 
                    false)
                ;

rule_t const    IDENTIFIER(
                    IDENTIFIER_HELPER[&last_Identifier]  >> isNotSpecialToken, 
                    false)
                ;

rule_t const    CLASS_NAME(
                      ( IDENTIFIER_HELPER[&last_Identifier] >> CLASS_NAME_HELPER) 
                    | (if_p(EPSILON[&enableTemplateName] >> TEMPLATE_NAME)[EPSILON[&disableTemplateName]]. 
                       else_p[EPSILON[&disableTemplateName] >> NOTHING]),
                    false)
                ;

rule_t const    ENUM_NAME(
                    IDENTIFIER_HELPER[&last_Identifier] >> ENUM_NAME_HELPER,
                    false)
                ;

rule_t const    TYPEDEF_NAME(
                    IDENTIFIER_HELPER[&last_Identifier] >> TYPEDEF_NAME_HELPER,
                    false)
                ;

rule_t const    NAMESPACE_ALIAS(
                    IDENTIFIER_HELPER[&last_Identifier] >> NAMESPACE_ALIAS_HELPER,
                    false)
                ;

rule_t const    ORIGINAL_NAMESPACE_NAME(
                    IDENTIFIER_HELPER[&last_Identifier] >> ORIGINAL_NAMESPACE_NAME_HELPER,
                    false)
                ;

rule_t const    TEMPLATE_NAME(
                    IDENTIFIER_HELPER[&last_Identifier] >> TEMPLATE_NAME_HELPER,
                    false)
                ;

rule_t const    EPSILON =
                    epsilon_p
                ;

rule_t const    NOTHING =
                    nothing_p
                ;

// MS extensions
rule_t const    MSEXT_ASM =
                    ch_p(T_MSEXT_ASM)
                ;
}  // namespace cnome
